package com.ctg.behavior.calc.impala.transfer;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.calc.common.CtSQLParam;
import com.ctg.behavior.calc.impala.CtSQLTransfer;
import com.ctg.behavior.calc.impala.report.CtCalcRestrictMeasureReport;
import com.ctg.behavior.calc.utils.CtCalcPropertyUtils;
import com.ctg.behavior.calc.utils.CtCalcSQLUtils;
import com.ctg.behavior.common.calc.CtCalc;
import com.ctg.behavior.common.calc.CtCalcRestrict;
import com.ctg.behavior.common.calc.CtCalcRestrictMeasure;
import com.ctg.behavior.common.consts.CtAggregatorConsts;
import com.ctg.behavior.common.consts.CtFunctionConsts;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtHavingRestrictTransfer implements CtSQLTransfer {

	@Override
	public String doTransfer(CtCalc calcObject, CtSQLParam sqlParam) {
		if (!(calcObject instanceof CtCalcRestrictMeasureReport)) {
			log.warn("calcObject is not CtCalcRestrictMeasureReport, class={}", calcObject.getClass());
			log.warn("calcObject: {}", JSON.toJSON(calcObject));
			return "";
		}
		CtCalcRestrictMeasure restrictMeasure = (CtCalcRestrictMeasure) calcObject;
		log.info("CalcBody={}", JSON.toJSONString(restrictMeasure));

		StringBuilder impalaSQL = new StringBuilder();
		impalaSQL.append(" HAVING ( ");

		// 1. 计算度量限制
		String aggregator = restrictMeasure.getAggregator();
		CtCalcRestrict restrict = restrictMeasure.getRestrict();
		String function = restrict.getFunction();
		String property = CtCalcPropertyUtils.getProperty(restrictMeasure.getField());
		// 2. 转换："aggregator" 符号
		String sqlAggregator = "";
		if (CtAggregatorConsts.KEY_GENERAL.equalsIgnoreCase(aggregator)) {
			// 总次数
			// sqlAggregator = "COUNT(device_id)";
			sqlAggregator = "COUNT(" + CtCalcSQLUtils.fillAlias("device_id", sqlParam) + ")";
		} else if (CtAggregatorConsts.KEY_SUM.equalsIgnoreCase(sqlAggregator)) {
			// 指定属性的总和
			// sqlAggregator = "SUM(" + property + ")";
			sqlAggregator = "SUM(" + CtCalcSQLUtils.fillAlias(property, sqlParam) + ")";
		} else if (CtAggregatorConsts.KEY_AVG.equalsIgnoreCase(sqlAggregator)) {
			// 指定属性的平均值
			// sqlAggregator = "AVG(" + property + ")";
			sqlAggregator = "AVG(" + CtCalcSQLUtils.fillAlias(property, sqlParam) + ")";
		} else if (CtAggregatorConsts.KEY_MAX.equalsIgnoreCase(sqlAggregator)) {
			// 指定属性的最大值
			// sqlAggregator = "MAX(" + property + ")";
			sqlAggregator = "MAX(" + CtCalcSQLUtils.fillAlias(property, sqlParam) + ")";
		} else if (CtAggregatorConsts.KEY_MIN.equalsIgnoreCase(sqlAggregator)) {
			// 指定属性的最小值
			// sqlAggregator = "MIN(" + property + ")";
			sqlAggregator = "MIN(" + CtCalcSQLUtils.fillAlias(property, sqlParam) + ")";
		} else if(CtAggregatorConsts.KEY_UNIQUE.equalsIgnoreCase(sqlAggregator)) {
			// 特殊处理：[分布 - 天数] 的计算条件
			// sqlAggregator = "COUNT(device_id)";
			sqlAggregator = "COUNT(" + CtCalcSQLUtils.fillAlias(property, sqlParam) + ")";
		}
		if(StringUtils.isEmpty(sqlAggregator)) {
			return "";
		}
		// 3. 处理 restrict function
		if (CtFunctionConsts.KEY_EQUAL.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" = ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_NOTEQUAL.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" <> ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_LESS.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" < ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_MOST.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" <= ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_GREATER.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" > ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_LEAST.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" >= ");
			impalaSQL.append(restrict.getParams().get(0));
		} else if (CtFunctionConsts.KEY_BETWEEN.equalsIgnoreCase(function)) {
			impalaSQL.append(sqlAggregator).append(" >= ").append(restrict.getParams().get(0));
			impalaSQL.append(" AND ");
			impalaSQL.append(sqlAggregator).append(" <= ").append(restrict.getParams().get(1));
		}
		
		impalaSQL.append(" ) ");
		String sqlCondtions = impalaSQL.toString();
		
		log.info("CalcSQL={}", sqlCondtions);

		return sqlCondtions;
	}

}
